package com.gin.kotlin.no_gay_alliance.utils

import android.content.Context
import android.util.Log
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.JavaType
import com.gin.kotlin.no_gay_alliance.app.App
import com.gin.retrofit.utils.JacksonUtils
import java.io.File

/**
 * 文件缓存工具类
 */
class FileCacheUtils {
    companion object {
        private val TAG = FileCacheUtils::class.java.simpleName

        private fun getCacheFile(relativePath: String, context: Context = App.INSTANCE) = File(context.cacheDir, relativePath)

        /**
         * 读取缓存文件
         * @param relativePath 文件在缓存目录中的相对路径
         * @param expires 过期时长(秒)
         * @param context 上下文
         * @return T?
         */
        fun <T> readCache(relativePath: String, expires: Long, javaType: JavaType? = null, context: Context = App.INSTANCE): T? {
            // 保存缓存数据的文件
            val cacheFile = getCacheFile(relativePath, context)
            // 缓存文件不存在 或 上次修改时间超过过期时长，则返回null
            if (!cacheFile.exists()) return null
            if (System.currentTimeMillis() - cacheFile.lastModified() > expires * 1000) return null
            // 缓存有效，读取文件内容转换为指定类型
            val text = cacheFile.readText()
            try {
                Log.d(TAG, "缓存命中: $relativePath")
                return if (javaType != null)
                    JacksonUtils.MAPPER.readValue(text, javaType)
                else
                    JacksonUtils.MAPPER.readValue(text, object : TypeReference<T>() {})
            } catch (e: Exception) {
                Log.w(TAG, "缓存读取失败: ${e.localizedMessage}")
                e.printStackTrace()
                return null
            }
        }

        /**
         * 写入缓存文件
         * @param relativePath 文件在缓存目录中的相对路径
         * @param data 数据
         * @param context 上下文
         */
        fun <T> writeCache(relativePath: String, data: T, context: Context = App.INSTANCE) {
            // 保存缓存数据的文件
            val cacheFile = getCacheFile(relativePath, context)
            // 如果父目录不存在，创建
            cacheFile.parentFile?.takeIf { !it.exists() }?.mkdirs()
            // 写入
            Log.d(TAG, "缓存写入: $relativePath")
            JacksonUtils.MAPPER.writeValue(cacheFile, data)
        }
    }
}